<template>
  <tiny-autocomplete
    ref="autoRef"
    v-model="name"
    hide-loading
    :debounce ="10"
    :value-key="labelKey"
    :select-when-unmatched="false"
    :fetch-suggestions="querySearch"
    :highlight-first-item="true"
    :size="size"
    :placeholder="placeholder"
    :disabled="disabled"
    :style="{ width: width ? width + 'px' : '100%' }"
    @blur="blur"
    @keydown="keydown"
    @mouseover="over=true"
    @mouseleave="over=false"
    @select="handleSelect"
  >
    <template #default="{ slotScope }">
      <div style="display: flex;">
        <div style="flex: 1; color: #333333; font-size: 14px;">
          <span>{{ slotScope.ext }}{{ slotScope[labelKey] }}</span>
        </div>
        <div style="padding-left: 10px; color: #8a8f97;font-size: 13px;">
          {{ slotScope.suffix }}
        </div>
      </div>
    </template>
    <template #suffix v-if="clearable && name && over" >
      <TinyIconClose @click="clear" />
    </template>
    <template #prepend v-if="showMore">
      <div style="cursor: pointer;text-align: center;padding: 0 5px;" title="弹出更多选择">
        <TinyIconMore></TinyIconMore>
      </div>
    </template>
  </tiny-autocomplete>
</template>

<script>
import { Autocomplete } from '@opentiny/vue'
import { IconMore, IconClose,} from '@opentiny/vue-icon'
import tool from "@/utils/tool";
export default {
  components: {
    TinyAutocomplete: Autocomplete,
    TinyIconMore: IconMore(),
    TinyIconClose: IconClose()
  },
  props: {
    width: { type: [String, Number], default: '' },
    modelValue: { type: [String, Number], default: '' },
    invId: { type: [String, Number], default: '' },
    buId: { type: [String, Number], default: '' },
    unit: { type: [String, Number], default: '' },
    transType: { type: [String, Number], default: '' },
    qty: { type: [String, Number], default: '' },
    sql: { type: String, default: '' },
    size: { type: String, default: 'small' },
    valueKey: { type: String, default: 'id' },
    labelKey: { type: String, default: 'name' },
    searchKey: { type: String, default: '' },
    showMore: { type: Boolean, default: false },
    strict: { type: Boolean, default: false }, // blur后，如果名称与id不对应，自动变更 名称
    disabled: { type: Boolean, default: false },
    clearable: { type: Boolean, default: true },
    isGrid: { type: Boolean, default: false }, // 下拉 表格
    list: { type: [String, Array], default: '' },
    focusOpen: { type: Boolean, default: true }, // focus自动打开
    readonly: { type: Boolean, default: false }, // 必填
    required: { type: Boolean, default: false }, // 必填
    pinYin: { type: Boolean, default: false }, // 拼音
    border: { type: Boolean, default: true }, // 禁用
    cat: { type: String, default: '' }, // 取数据cat分类
    placeholder: { type: String, default: '' }, // 取数据cat分类
    options: {
      type: Array,
      default: () => {
        return [];
      },
    }, // 如果传入值
  },
  data() {
    return {
      IconMore: IconMore(),
      name: this.modelValue,
      over: false,
      id: null,
      lists: [],
      opened: false
    }
  },
  emits: ['update:modelValue', 'update:id', 'change', 'enter', 'Esc', 'down', 'up', 'left', 'right', 'clickMore'],
  methods: {
    clear () {
      this.id = null
      this.name = ''
      this.$emit('update:id', this.id)
      this.$emit('update:modelValue', this.name)
      this.$emit('change', null)
    },
    querySearch(queryString, cb) {
      queryString = tool.xe.trim(queryString)
      if(this.list.length > 0) {
        let list = this.list.filter(row => {
          return row.name.indexOf(queryString) !== -1
        })
        cb(list)
        this.lists = list
      }
      else if (this.sql) {
        let sql = this.sql;
        if (queryString) {
          if (this.pinYin) {
            sql += ` and (${this.labelKey} like '%${queryString}%' or pinYin like '%${queryString}%') `;
          } else {
            sql += ` and ${this.labelKey} like '%${queryString}%' `;
          }
        }
        tool.post('common/doSql', { sql: sql }).then((ret) => {
          cb(ret.data)
          this.lists = ret.data
        })
      }
      else if(this.cat) {
        tool.post('common/dropdown', {
            cat: this.cat,
            keyWord: queryString,
            invId: this.invId,
            buId: this.buId,
            unit: this.unit,
            transType: this.transType,
            qty: this.qty,
          })
          .then((ret) => {
            if (ret.stat) {
              cb(ret.data)
              this.lists = ret.data
            }
          })
      }
      this.opened = true
    },
    handleSelect(item) {
      if (item instanceof Event) return
      this.currentRow = item
      this.name = item[this.labelKey]
      this.id = item[this.valueKey]
      this.$emit('update:id', this.id)
      this.$emit('update:modelValue', this.name)
      this.$emit('change', item)
      this.opened = false
    },
    blur () {
      this.opened = false
      if(!tool.xe.trim(this.name)) {
        if(this.id) {
          this.clear()
        }
      }
      if(this.strict) {
        // 如果修改了名称，还原
        if(this.id && this.name) {
          let lis = this.lists.filter(row => {
            return row.id === this.id
          })
          if(lis && lis.length === 1) {
            if(this.name !== lis[0].name) {
              this.name = lis[0].name
              this.$emit('update:modelValue', this.name)
            }
          }
        }
        else if (this.name && !this.id) {
          this.name = ''
          this.$emit('update:modelValue', this.name)
        }
      }
    },
    keydown (e) {
      let key = e.key ? e.key : e.$event.key;
      let start = e.target.selectionStart; // 光标位置
      if(!this.opened) return
      e.stopImmediatePropagation()
      switch (key) {
        case 'Enter':
        {
          this.$emit('enter');
        }
          break;
        case 'ArrowLeft':
        {
          if (start === 0) {
            this.$emit('left');
          }
        }
          break;
        case 'ArrowRight':
        {
          if (start === (this.modelValue ? tool.xe.toString(this.modelValue).length : 0)) {
            this.$emit('right');
          }
        }
          break;
        case 'ArrowDown':
        {
          this.$emit('down');
        }
          break;
        case 'ArrowUp':
        {
          this.$emit('up');
        }
          break;
        case 'Escape':
        {
          this.$emit('Esc');
        }
          break;
      }
    },
  },
}
</script>

<style lang="scss">
.tiny-input-group__append,.tiny-input-group__prepend {
  padding: 0 !important;
}
</style>
